import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
import { CheckOutlined } from '@ant-design/icons';
import { Divider, Select, SelectProps } from 'antd';
import classNames from 'classnames';
import { useThrottleFn } from 'ahooks';
import './index.less';

const { Option } = Select;

interface DataItem {
  [x: string]: any;
  label: string;
  key: string;
}

export const DropDownRender: React.FC<{
  extra?: string | ((item: DataItem) => string);
  value: string[];
  data: DataItem[];
  onItemClick: (item: DataItem, checked: boolean) => void;
  iconRender?: (item: DataItem) => ReactNode;
  emptyRender?: () => ReactNode;
  searchValue: string;
}> = (props) => {
  const scrollRef = useRef(null);
  const [focusIndex, _focusIndex] = useState(-1);
  const { data, extra, value, iconRender, emptyRender, searchValue } = props;
  const getExtra = useCallback(
    (item: DataItem) => (extra ? (typeof extra == 'function' ? extra(item) : item[extra]) : null),
    [extra],
  );

  const renderLabel = useCallback(
    (label: string, rowIndex: number) => {
      let index = label.toLowerCase().indexOf(searchValue.toLowerCase());
      if (index > -1) {
        const arr = [
          label.slice(0, index),
          label.slice(index, index + searchValue.length),
          label.slice(index + searchValue.length),
        ];
        return (
          <span>
            {arr.map((item, i) => (
              <span
                key={`label-${rowIndex}-${i}`}
                style={i == 1 ? { color: 'var(--inbiz-color-primary)' } : {}}
              >
                {item}
              </span>
            ))}
          </span>
        );
      }
      return <span>{label}</span>;
    },
    [searchValue],
  );

  const renderItem = useCallback(
    (item: DataItem, index: number) => {
      const isActive = (value || []).indexOf(item.key) > -1;
      return (
        <div
          key={item.key}
          className={classNames('inbiz-EformMemberSelect-DropdownItem', {
            active: isActive,
            isFocus: focusIndex == index,
          })}
          onClick={(e) => {
            props.onItemClick(item, !isActive);
          }}
          onMouseEnter={(e) => {
            _focusIndex(index);
          }}
        >
          {iconRender?.(item) || null}
          <div title={item.label}>{renderLabel(item.label, index)}</div>
          <div>{getExtra(item)}</div>
          {isActive ? <CheckOutlined /> : null}
        </div>
      );
    },
    [focusIndex, value, getExtra, props.onItemClick, renderLabel],
  );

  const bindKeyboardEvents = useCallback(
    (e: any) => {
      if (e.keyCode == 40) {
        // 下一个
        if (focusIndex < data.length - 1) {
          _focusIndex(focusIndex + 1);
          scrollRef.current?.scrollTo(0, 40 * (focusIndex + 1));
        }
      } else if (e.keyCode == 38) {
        // 上一个
        if (focusIndex > 0) {
          _focusIndex(focusIndex - 1);
          scrollRef.current?.scrollTo(0, 40 * (focusIndex - 1));
        }
      } else if (e.keyCode == 13) {
        // Enter
        const item = data[focusIndex];
        if (item) {
          const isActive = (value || []).indexOf(item.key) > -1;
          props.onItemClick(item, !isActive);
        }
      }
    },
    [data, focusIndex, value, scrollRef],
  );

  useEffect(() => {
    _focusIndex(data.length ? 0 : -1);
  }, [data]);

  useEffect(() => {
    document.addEventListener('keydown', bindKeyboardEvents, false);
    return () => {
      document.removeEventListener('keydown', bindKeyboardEvents, false);
    };
  }, [bindKeyboardEvents]);

  return (
    <div
      ref={scrollRef}
      className={classNames('inbiz-EformMemberSelect-Dropdown', {
        'ant-select-dropdown-empty': !data.length,
      })}
    >
      {data.map(renderItem)}
      {data.length ? null : emptyRender?.()}
    </div>
  );
};

const SelectExtend: React.FC<{
  selectProps?: SelectProps;
  addonBefore?: {
    title: string;
    icon?: ReactNode;
    onClick: (e: any) => void;
    disabled?: boolean;
  };
  className?: string;
  options: {
    [x: string]: any;
    label: string;
    value: string;
    key: string;
  }[];
  componentIsInline: boolean;
  inlineEditContent: Array<string>;
  readOnly?: Boolean;
}> = (props) => {
  const { selectProps, addonBefore, options, componentIsInline, inlineEditContent, readOnly } =
    props;
  const Options = (options || []).map((d, i) => (
    <Option key={`${d.key}-${i}`} value={d.value} data-value={d.data}>
      {d.label}
    </Option>
  ));
  const [addClass, $addClass] = useState<boolean>(false);
  const { run } = useThrottleFn((b: boolean) => $addClass(b), 100);
  const componentIsInlineClass = selectProps?.mode === 'tags' ? 'single-mode' : 'multiple-mode';
  return (
    <div
      className={
        addClass
          ? `inbiz-EformSelectMember-SelectExtend active-focus ${componentIsInline ? componentIsInlineClass : ''
          }${readOnly ? 'readOnly' : ''}`
          : `inbiz-EformSelectMember-SelectExtend ${componentIsInline ? componentIsInlineClass : ''
          }${readOnly ? 'readOnly' : ''}`
      }
      onFocus={() => run(true)}
      onBlur={() => run(false)}
    >
      {!componentIsInline && (
        <Select
          {...selectProps}
          className={classNames(
            'inbiz-EformSelectMember-SelectExtend-select',
            selectProps?.className,
          )}
          dropdownStyle={{ minWidth: props.componentIsInline ? '200px' : 'initial' }}

          suffixIcon={<div>dfsdfsdfsdf</div>}
        >
          {Options}

        </Select>

      )}
      {componentIsInline && selectProps?.mode === 'tags' && <span>{inlineEditContent}</span>}
      {
        addonBefore ? (
          <span
            className={classNames('inbiz-EformSelectMember-SelectExtend-addonBefore-us', {
              disabled: !!addonBefore.disabled,
            })}
            onClick={(e) => {
              if (addonBefore.disabled) {
                return
              } else {
                addonBefore.onClick(e);
              }
            }}
          >
            {addonBefore.icon || null}
            {/* {addonBefore.title} */}
          </span>
        ) : null
      }

    </div>
  );
};

export default SelectExtend;
